package com.xiaoshuidi.cloud.module.iot.service.impl;



import com.alibaba.fastjson.JSONObject;
import com.xiaoshuidi.cloud.module.iot.dal.model.callback.TianchengCallbackReqVO;
import com.xiaoshuidi.cloud.module.iot.dal.model.callback.TianchengContants;
import com.xiaoshuidi.cloud.module.iot.dal.model.callback.TianchengDeviceCallbackResVO;
import com.xiaoshuidi.cloud.module.iot.dal.model.device.TbDeviceDosageCallbackModel;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbDeviceDo;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbDoorlockPassword;
import com.xiaoshuidi.cloud.module.iot.dal.repository.DeviceRepository;
import com.xiaoshuidi.cloud.module.iot.dal.repository.TbDoorLockPasswordRepository;
import com.xiaoshuidi.cloud.module.iot.enums.BrandEnum;
import com.xiaoshuidi.cloud.module.iot.enums.PasswordStatusEnum;
import com.xiaoshuidi.cloud.module.iot.enums.PasswordTypeEnum;
import com.xiaoshuidi.cloud.module.iot.service.LocalCallbackService;
import com.xiaoshuidi.cloud.module.iot.service.TianchengCallbackService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import spring.cloud.sdiot.biz.dataaccess.DeviceDataAccess;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;

@Service
public class TianchengCallbackServiceImpl implements TianchengCallbackService {

    private Logger LOGGER = LoggerFactory.getLogger(TianchengCallbackServiceImpl.class);

    @Autowired
    private LocalCallbackService localCallbackService;
    @Autowired
    private DeviceRepository deviceDataAccess;
    @Autowired
    private TbDoorLockPasswordRepository doorLockPasswordDataAccess;

    @Override
    //数据库事务控制，在我们一个业务流程中操作多个数据表使用，以保证事务原子性；注：本类调用方法会导致事务失效，必须走代理
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public TianchengDeviceCallbackResVO disposeCallback(TianchengCallbackReqVO tianchengDeviceCallbackReqVO) throws Exception {
        TianchengDeviceCallbackResVO tianchengDeviceCallbackResVO = new TianchengDeviceCallbackResVO();
        String pushType = tianchengDeviceCallbackReqVO.getPushType();
        JSONObject pushContent = tianchengDeviceCallbackReqVO.getPushContent();
        String imei = tianchengDeviceCallbackReqVO.getImei();
        switch (pushType) {
            //设备状态变化
            case TianchengContants.DEVICE_STATUS_CHANGES :
                Integer onlineStatus;
                Integer deviceStatusType = pushContent.getInteger("deviceStatusType");
                switch (deviceStatusType) {
                    case 3 :
                        onlineStatus = 0;
                        break;
                    default:
                        onlineStatus = 1;
                        break;
                }
                //设备电量
                Integer batteryLevel = pushContent.getInteger("batteryLevel");
                Double batteryPercent = Double.valueOf(String.valueOf(batteryLevel));
                disposDeviceStatus(imei, BrandEnum.TIANCHENG.getBrand(),onlineStatus,null,batteryPercent);
                tianchengDeviceCallbackResVO.setStatus("200");
                tianchengDeviceCallbackResVO.setMessage("天诚回调-修改设备状态成功");
                break;
            //密码同步
            case TianchengContants.PASSWORD_SYNCHRONIZATION :
                TbDoorlockPassword doorlockPassword = new TbDoorlockPassword();
                String passwordId = pushContent.getString("passwordId");
                doorlockPassword.setThirdPasswordId(passwordId);
                String operationType = pushContent.getString("operationType");
                switch (operationType) {
                    case "1" :
                        //密码回调-添加普通密码成功，将密码状态修改为1生效状态
                        if(2 == pushContent.getInteger("passwordType")){
                            doorlockPassword.setPasswordStatus(PasswordStatusEnum.VALID.getCode());
                            disposeUpdatePassword(doorlockPassword);
                            tianchengDeviceCallbackResVO.setStatus("200");
                            tianchengDeviceCallbackResVO.setMessage("天诚回调-添加普通密码操作成功");
                        }
                        //密码回调-添加指纹密码成功，将指纹密码落库 - 注: 天诚指纹密码并不是由我们系统下发,是东苑其他合作商完成这一动作,但会回调到我们系统,我们将其落库以进行冻结/解冻操作
                        if(1 == pushContent.getInteger("passwordType")){
                            TbDeviceDo deviceDoQueryParam = new TbDeviceDo();
                            deviceDoQueryParam.setDeviceThirdNo(imei);
                            deviceDoQueryParam.setBrandNo(BrandEnum.TIANCHENG.getBrand());
                            TbDeviceDo td = deviceDataAccess.getTbDeviceByConditon(deviceDoQueryParam);
                            doorlockPassword.setThirdPasswordId(passwordId);
                            doorlockPassword.setPasswordStatus(PasswordStatusEnum.VALID.getCode());
                            doorlockPassword.setStatus(1);
                            //此处根据2023-07-13 10:15:00 与天诚会议确定，他们返回了密码值
                            doorlockPassword.setPassword(pushContent.getString("password"));
                            doorlockPassword.setDeviceNo(td.getDeviceNo());
                            //天诚指纹密码设置默认值
                            doorlockPassword.setMemberName("指纹密码");
                            doorlockPassword.setMemberType("租客");
                            //
                            doorlockPassword.setAuthType(Integer.valueOf(PasswordTypeEnum.FINGER_DIGIT.getTypeCode()));
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            Date startTime = sdf.parse(pushContent.getString("startTime"));
                            Date endTime = sdf.parse(pushContent.getString("endTime"));
                            doorlockPassword.setValidStarttime(startTime);
                            doorlockPassword.setValidEndtime(endTime);
                            //doorlockPassword.setCreateUser(10001);
                            doorlockPassword.setCreateTime(LocalDateTime.now());
                            doorLockPasswordDataAccess.save(doorlockPassword);
                            tianchengDeviceCallbackResVO.setStatus("200");
                            tianchengDeviceCallbackResVO.setMessage("天诚回调-添加指纹密码操作成功");
                        }
                        break;
                    case "2" :
                        //密码回调-修改密码成功，将密码有效时间同步
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        Date startTime = sdf.parse(pushContent.getString("startTime"));
                        Date endTime = sdf.parse(pushContent.getString("endTime"));
                        doorlockPassword.setValidStarttime(startTime);
                        doorlockPassword.setValidEndtime(endTime);
                        disposeUpdatePassword(doorlockPassword);
                        tianchengDeviceCallbackResVO.setStatus("200");
                        tianchengDeviceCallbackResVO.setMessage("天诚回调-修改密码操作成功");
                        break;
                    case "3" :
                        //删除密码-密码状态改为过期状态
                        doorlockPassword.setPasswordStatus(PasswordStatusEnum.EXPIRED.getCode());
                        //密码记录数据状态改为无效
                        doorlockPassword.setStatus(0);
                        disposeUpdatePassword(doorlockPassword);
                        tianchengDeviceCallbackResVO.setStatus("200");
                        tianchengDeviceCallbackResVO.setMessage("天诚回调-删除密码操作成功");
                        break;
                    case "4" :
                        //密码状态改为冻结状态
                        doorlockPassword.setPasswordStatus(PasswordStatusEnum.FROZEN.getCode());
                        disposeUpdatePassword(doorlockPassword);
                        tianchengDeviceCallbackResVO.setStatus("200");
                        tianchengDeviceCallbackResVO.setMessage("天诚回调-冻结密码操作成功");
                        break;
                    case "5" :
                        //密码解冻-密码状态改为生效状态
                        doorlockPassword.setPasswordStatus(PasswordStatusEnum.VALID.getCode());
                        disposeUpdatePassword(doorlockPassword);
                        tianchengDeviceCallbackResVO.setStatus("200");
                        tianchengDeviceCallbackResVO.setMessage("天诚回调-开门记录推送操作成功");
                        break;
                }
                break;
            //开门记录
            case TianchengContants.OPEN_DOOR_RECORDS :
                disposOpenRecord(tianchengDeviceCallbackReqVO);
                tianchengDeviceCallbackResVO.setStatus("200");
                tianchengDeviceCallbackResVO.setMessage("天诚回调-开门通知成功");
                break;
        }
        return tianchengDeviceCallbackResVO;
    }

    private void disposDeviceStatus(String imei, String shuidiBrand, Integer onlineStatus, Integer status,Double batteryLevel ) throws Exception {
        TbDeviceDo tbDeviceDo = new TbDeviceDo();
        //第三方设备编号， 即天诚的设备唯一标识
        tbDeviceDo.setDeviceThirdNo(imei);
        //第三方设备品牌
        tbDeviceDo.setBrandNo(shuidiBrand);
        tbDeviceDo.setOnlineStatus(onlineStatus);
        //设备通电状态
        tbDeviceDo.setPowerStatus(status);
        //设备电量
        tbDeviceDo.setBatteryLevel(batteryLevel);
        //处理水滴IOT本地更新数据业务
        localCallbackService.tianchengUpdateTbDeviceRecord(tbDeviceDo);
    }

    /**
     *  操作密码通知回调
     *  在此回调执行之前, 密码状态为执行中, 回调成功, 密码状态修改
     * @param
     */
    private void disposeUpdatePassword(TbDoorlockPassword password){
        password.setUpdateTime(LocalDateTime.now());
        doorLockPasswordDataAccess.updateTianchengPasswordByPasswordId(password);
    }

    /**
     *  开门记录推送
     * @param tianchengCallbackReqVO
     */
    private void disposOpenRecord(TianchengCallbackReqVO tianchengCallbackReqVO){
        String imei = tianchengCallbackReqVO.getImei();
        JSONObject params = tianchengCallbackReqVO.getPushContent();
        TbDeviceDo deviceDoQueryParam = new TbDeviceDo();
        deviceDoQueryParam.setDeviceThirdNo(imei);
        deviceDoQueryParam.setBrandNo(BrandEnum.TIANCHENG.getBrand());
        //根据brandNo与第三方设备编号deviceThirdNo定位设备
        TbDeviceDo td = deviceDataAccess.getTbDeviceByConditon(deviceDoQueryParam);
        if(null == td){
            throw new RuntimeException("未找到门锁");
        }
        //查询该设备是否存在有效密码
        TbDoorlockPassword tbDoorlockPassword = new TbDoorlockPassword();
        tbDoorlockPassword.setDeviceNo(td.getDeviceNo());
        tbDoorlockPassword.setThirdPasswordId(params.getString("passwordId"));
        tbDoorlockPassword.setStatus(1);
        //根据设备编号，密码id,密码生效状态, 查询除有效密码
        tbDoorlockPassword = doorLockPasswordDataAccess.getPassWordThirdPassWordId(tbDoorlockPassword.getDeviceNo(), tbDoorlockPassword.getThirdPasswordId());
        JSONObject openRecord = new JSONObject();
        openRecord.put("userId", params.getString("passwordId"));
        openRecord.put("recordTime", new Date());
        String passwordType = params.getString("passwordType");
        if("2".equals(passwordType)){
            //开门方式-普通密码开锁
            openRecord.put("opType", "tenantPwd");
            LOGGER.info("天诚-开锁事件上报回调-有效普通密码为：{}", JSONObject.toJSONString(tbDoorlockPassword));
        }else if("4".equals(passwordType)){
            //开门方式-动态密码开锁
            openRecord.put("opType", "dynamicPwd");
            LOGGER.info("天诚-开锁事件上报回调-动态密码为：{}", JSONObject.toJSONString(tbDoorlockPassword));
            //一次性密码（临时密码）， 门开完密码就失效，临时密码不落库，用完直接物理删除即可
            TbDoorlockPassword tbDoorlockPasswordCondition = new TbDoorlockPassword();
            tbDoorlockPasswordCondition.setDeviceNo(td.getDeviceNo());
            tbDoorlockPasswordCondition.setThirdPasswordId(params.getString("passwordId"));
            //直接物理删除，这里直接用经纬纵横的物理删除密码接口就行，反正都是要删密码的
            doorLockPasswordDataAccess.deleteIsurpassDoorLockPasswordRecordByDeviceNoAndPasswordId(tbDoorlockPasswordCondition);
        }else if("1".equals(passwordType)){
            //开门方式-指纹密码开锁
            openRecord.put("opType", "fingerprintPwd");
            LOGGER.info("天诚-开锁事件上报回调-指纹密码为：{}", JSONObject.toJSONString(tbDoorlockPassword));
        }
            //此处返回开门记录
            TbDeviceDosageCallbackModel tbDeviceDosageCallbackModel = new TbDeviceDosageCallbackModel();
            tbDeviceDosageCallbackModel.setOpenRecord(openRecord);
            tbDeviceDosageCallbackModel.setTbDeviceDo(td);
        try {
            //开门记录回调处理
            localCallbackService.disposeOpenRecordCallback(tbDeviceDosageCallbackModel);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error(e.getMessage());
        }

    }

}
